"""
PLC客户端基类

定义所有PLC客户端的通用接口和基本功能
"""

import logging
from abc import ABC, abstractmethod
from typing import List, Optional, Union

# 配置日志记录
logging.basicConfig(
    format='%(asctime)s - %(levelname)s - %(message)s',
    level=logging.INFO
)
logger = logging.getLogger(__name__)


class BasePLCClient(ABC):
    """PLC客户端基类，定义所有PLC客户端的通用接口"""
    
    def __init__(self):
        self.client = None
        self.connected = False
        
    @abstractmethod
    def connect(self) -> bool:
        """
        连接到PLC设备
        
        返回:
            bool: 连接成功返回True，失败返回False
        """
        pass
    
    @abstractmethod
    def close(self) -> None:
        """关闭PLC连接"""
        pass
    
    def is_connected(self) -> bool:
        """
        检查连接状态
        
        返回:
            bool: 已连接返回True，未连接返回False
        """
        return self.connected and self.client is not None
    
    # 寄存器读写接口（可选实现）
    def read_registers(self, start_address: int, count: int = 1) -> Optional[List[int]]:
        """
        读取寄存器（通用接口）
        
        参数:
            start_address: 起始地址
            count: 读取数量
            
        返回:
            Optional[List[int]]: 寄存器值列表，失败返回None
        """
        raise NotImplementedError("子类需要实现此方法")
    
    def write_registers(self, start_address: int, values: List[int]) -> bool:
        """
        写入寄存器（通用接口）
        
        参数:
            start_address: 起始地址
            values: 要写入的值列表
            
        返回:
            bool: 写入成功返回True，失败返回False
        """
        raise NotImplementedError("子类需要实现此方法")
    
    # 线圈读写接口（可选实现）
    def read_coils(self, start_address: int, count: int = 1) -> Optional[List[bool]]:
        """
        读取线圈（通用接口）
        
        参数:
            start_address: 起始地址
            count: 读取数量
            
        返回:
            Optional[List[bool]]: 线圈状态列表，失败返回None
        """
        raise NotImplementedError("子类需要实现此方法")
    
    def write_coils(self, start_address: int, values: List[bool]) -> bool:
        """
        写入线圈（通用接口）
        
        参数:
            start_address: 起始地址
            values: 要写入的状态列表
            
        返回:
            bool: 写入成功返回True，失败返回False
        """
        raise NotImplementedError("子类需要实现此方法")
    
    # 测试连接功能
    def test_connection(self) -> bool:
        """
        测试连接是否正常
        
        返回:
            bool: 测试成功返回True，失败返回False
        """
        if not self.is_connected():
            logger.error("客户端未连接，无法进行测试")
            return False
        
        # 子类可以重写此方法以实现特定的测试逻辑
        return True
    
    def get_device_info(self) -> dict:
        """
        获取设备信息
        
        返回:
            dict: 设备信息字典
        """
        return {
            "type": self.__class__.__name__,
            "connected": self.is_connected(),
        }
